02 Polimorfismo

Próxima Atividade
  • Sugerir melhoria
Play
Current Time 0:00
/
Duration Time 0:00
Remaining Time -0:00
Stream TypeLIVE
Loaded: 0%
Progress: 0%
0:00
Fullscreen
00:00
Mute
Playback Rate
  • 2x
  • 1.5x
  • 1.2x
  • 1x
  • 0.8x
  • 0.7x
1x
Subtitles
  • subtitles off
Captions
  • captions off
Chapters
  • Chapters
HD
Desculpe-nos pelo transtorno, mas este video não pode ser carregado, tente novamente.

Transcrição

Uma solução é criarmos a classe Imprimivel para que seja herdada por Negociacao Negociacoes. Como Negociacao é um Imprimivel e Negociacoes também, podemos referenciar instâncias dessas classes através do tipo Imprimivel. Como a super classe não sabe de antemão qual a implementação do método paraTexto(), vamos torná-lo um método abstrato, aquele que obriga a classe filha implementá-lo.

// app/ts/models/Imprimivel.ts

export abstract class Imprimivel {

    abstract paraTexto(): void;
}
export * from './Negociacao';
export * from './Negociacoes';
export * from './NegociacaoParcial';
export * from './Imprimivel';

Agora, só precisamos estender a classe Imprimivel em Negociacao e Negociacoes. Como ambas já possuem o método paraTexto() com a mesma assinatura (forma) do método abstrato, não teremos erro de compilação pois já atendemos a obrigação de implementar o método:

import { Imprimivel } from './Imprimivel';

export class Negociacao extends Imprimivel {

    constructor(readonly data: Date, readonly quantidade: number, readonly valor: number) {

        super();
    }

    get volume() {

        return this.quantidade * this.valor;
    }

    paraTexto(): void {
        console.log('-- paraTexto --');
        console.log(
            `Data: ${this.data}
            Quantidade: ${this.quantidade}, 
            Valor: ${this.valor}, 
            Volume: ${this.volume}`
        )
    }
}

Veja que não bastou apenas estender Imprimivel, como o constructor da classe filha é diferente da classe pai, fomos obrigados a chamar super() no constructor da classe filha para que o constructor da classe pai seja chamado.

Agora, faremos a mesma coisa com Negociacoes:

import { Negociacao } from './Negociacao';
import { Imprimivel } from './Imprimivel';

export class Negociacoes extends Imprimivel {

    private _negociacoes: Negociacao[] = [];

    adiciona(negociacao: Negociacao): void {

        this._negociacoes.push(negociacao);
    }

    paraArray(): Negociacao[] {

        return ([] as Negociacao[]).concat(this._negociacoes);
    }

    paraTexto(): void {
        console.log('-- paraTexto --');
        console.log(JSON.stringify(this._negociacoes));
    }
}

Neste caso, não precisamos chamar super(), porque a classe filha não define um constructor e, nesse caso, por padrão, o TypeScript adotará o constructor da classe pai.

Por fim, basta alterarmos agora nossa função impressão para que trabalhe com um array do tipo Imprimivel[]:

import { Imprimivel } from '../models/index';

export function imprime(...objetos: Imprimivel[]) {
    objetos.forEach(objeto => objeto.paraTexto());
}

Veja que o autocomplete funciona, mostrando apenas os métodos disponíveis na classe pai, omitindo os métodos classe filha. Não há problema nenhum nisso, porque queremos apenas lidar com objetos que são imprimíveis, e basta eles terem o método paraTexto().

Agora, em NegociacaoController, nosso código não compilará, porque Date não é um Imprimivel:

Argument of type 'Date' is not assignable to parameter of type 'Imprimivel'.

Ao removermos o parâmetro inválido (que não fazia mesmo sentido passarmos) nosso código volta a compilar. Lançamos mão do polimorfismo que consiste em tratar instâncias de objetos de diferentes formas. Sendo assim, apesar de na memória termos objetos do tipo Negociacao e Negociacoes, eles são referênciados através do tipo Imprimivel. Contudo, nossa solução ainda não esta 100% e precisamos meditar sobre ela antes de continuarmos.

Tirar dúvida Próxima Atividade
ícone TypeScript parte 2: Mais técnicas e boas práticas

TypeScript parte 2: Mais técnicas e boas práticas

100%
Aula05 de 05

Mais sobre interfaces

Atividades 2 de 17

  • 01 Chega de múltiplos console.log 13min
  • 02 Polimorfismo 11min
  • 03 Interface de método 06min
  • 04 Interface em ação
  • 05 Evitando importar negociações duplicadas 09min
  • 06 Estendendo interfaces 04min
  • 07 Sabatina
  • 08 Sintaxe inválida
  • 09 Para saber mais: TypeScript e Node.js
  • 10 Union Types e Type Guards
  • 11 Type alias
  • 12 Revisão 02min
  • 13 Mensagens de alto nível 03min
  • 14 Async/wait 11min
  • 15 Consolidando seus conhecimentos
  • 16 Considerações finais 01min
  • 17 Projeto final completo

Aulas

Outros Links

Fórum Trocar Curso
Gravatar de Marcos Katsumi Kay

Marcos Katsumi Kay 34.0k xp

Logo da Alura